package org.pub.lunch.mashup.google;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.pub.app.lunch.R;

import android.content.Context;
import android.graphics.drawable.Drawable;
import android.location.Location;
import android.os.Handler;
import android.util.Log;

public class QueryAsync extends QueryHandler implements Runnable {
	private static final String TAG = QueryAsync.class.toString();
	private final ExecutorService pool;
	private Handler handler;
	public static final int RESTAURANT_DATA = 0;
	public static final int QUERYASYNC_ERROR = 1;
	public static final int QUERYASYNC_NODATA = 2;
	private static final int THREAD_POOL_SIZE = 5;
	private static final int MAX_TRY = 100;
	private boolean alive;

	public synchronized boolean isAlive() {
		return alive;
	}

	public synchronized void setAlive(boolean alive) {
		this.alive = alive;
	}

	public QueryAsync(Context context, Location loc, Handler handler) {

		super(context, loc);
		// TODO Auto-generated constructor stub
		alive = true;
		this.handler = handler;
		pool = Executors.newFixedThreadPool(THREAD_POOL_SIZE);
	}

	// @Override
	public void run() {
		// TODO Auto-generated method stub
		Log.i(TAG, "Start");
		try {
			LocalAgent agent = new LocalAgent(getContext(), getLocation());
			List<Restaurant> results;
			int counter = 0;
			for (int i = 0; alive && (counter < LocalAgent.RESTAURANT_LIMIT) && i < MAX_TRY && ((results = agent.getStepByStep()) != null) && results.size() > 0; i++) {
				for (Restaurant r : results) {
					pool.execute(new ImageExtractor(handler, r));
					counter++;
				}
			}
			if (counter == 0) {
				pool.shutdown();
				handler.sendMessage(handler.obtainMessage(QUERYASYNC_NODATA));
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			pool.shutdown();
			handler.sendMessage(handler.obtainMessage(QUERYASYNC_ERROR, e));
		}

	}

	protected class ImageExtractor implements Runnable {
		Handler handler;
		Restaurant restaurant;

		public ImageExtractor(Handler handler, Restaurant restaurant) {
			this.handler = handler;
			this.restaurant = restaurant;
		}

		// @Override
		public void run() {
			// TODO Auto-generated method stub
			URL url = restaurant.getPhotoUrl();
			if (url != null) {
				try {
					Log.i("Image Request", url.toString());
					InputStream is = (InputStream) url.getContent();

					if (is != null) {
						restaurant.setDrawable(Drawable.createFromStream(is, url.toExternalForm()));
					}
				} catch (IOException e) {
					e.printStackTrace();
				}
			} else {
				restaurant.setDrawable(getContext().getResources().getDrawable(R.drawable.noimage));
			}
			handler.sendMessage(handler.obtainMessage(RESTAURANT_DATA, restaurant));

		}

	}
}
